/* File name       :  ioctl.c
 * Author          :  Wentao Shang
 *
 * Contents        :
 *    This file implements a standard user-mode ioctl program, run './ioctl'
 *    to see usage of this program.
 *
 */

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "iocommon.h"

void printUsage()
{
	printf("ioctl command usage: \n\n");
	printf("  To Get Mod:                             ./ioctl 1\n");
	printf("  To Get Res:                             ./ioctl 2\n");
	printf("  To Set Mod:                             ./ioctl 3 x\n");
	printf("  To Set Res:                             ./ioctl 4 x\n");
	printf("  To Enable Mod/Res Auto-configuration:   ./ioctl 5\n");
	printf("  To Disable Mod/Res Auto-configuration:  ./ioctl 6\n");
	printf("  To Get Time-out:                        ./ioctl 7\n");
	printf("  To Set Time-out:                        ./ioctl 8 x\n");
	printf("\nFor more infomation, please contact 'wentaoshang@gmail.com'.\n");
}

int main(int argc, char *argv[])
{
	int file_desc, ret_val;
	int cmd;
	unsigned short var;
	long time;
	
	printf("\n");
	
	file_desc = open(DEVICE_FILE_NAME, O_RDWR, S_IRUSR | S_IWUSR);
	if (file_desc < 0) {
		printf("Can’t open device file: %s\n\n", DEVICE_FILE_NAME);
		return -1;
	}

	if( argc == 1 )
		printUsage();
	
	if( argc == 2 ) {
		cmd = atoi(argv[1]);
		
		switch(cmd) {
			case 1:
				ret_val = ioctl(file_desc, IOCTL_GET_MOD, &var);
				if( ret_val < 0 )
					printf("ioctl_get_mod failed!\n");
				else
					printf("Current Mod is %u.\n", var);
				break;
			case 2:
				ret_val = ioctl(file_desc, IOCTL_GET_RES, &var);
				if( ret_val < 0 )
					printf("ioctl_get_res failed!\n");
				else
					printf("Current Res is %u.\n", var);
				break;
			case 5:
				ret_val = ioctl(file_desc, IOCTL_SET_AUTOCONFIG, NULL);
				if( ret_val < 0 )
					printf("ioctl_set_autoconfig failed!\n");
				else
					printf("Mod/Res Auto-configuration enabled.\n");
				break;
			case 6:
				ret_val = ioctl(file_desc, IOCTL_UNSET_AUTOCONFIG, NULL);
				if( ret_val < 0 )
					printf("ioctl_unset_autoconfig failed!\n");
				else
					printf("Mod/Res Auto-configuration disabled.\n");
				break;
			case 7:
				ret_val = ioctl(file_desc, IOCTL_GET_TIMEOUT, &time);
				if( ret_val < 0 )
					printf("ioctl_get_timeout failed!\n");
				else
					printf("Current Time-out is %ld.\n", time);
				break;
			default:
				printf("Invalid input format!\n");
				printUsage();
		}
	}
	
	if( argc == 3 ) {
		cmd = atoi(argv[1]);
		var = atoi(argv[2]);
		
		switch(cmd) {
			case 3:
				var = 1 << var;
				ret_val = ioctl(file_desc, IOCTL_SET_MOD, &var);
				if( ret_val < 0 )
					printf("ioctl_set_mod failed!\n");
				else
					printf("Set Mod to %u.\n", var);
				break;
			case 4:
				ret_val = ioctl(file_desc, IOCTL_SET_RES, &var);
				if( ret_val < 0 )
					printf("ioctl_set_res failed!\n");
				else
					printf("Set Res to %u.\n", var);
				break;
			case 8:
				time = (long)var;
				ret_val = ioctl(file_desc, IOCTL_SET_TIMEOUT, &time);
				if( ret_val < 0 )
					printf("ioctl_set_timeout failed!\n");
				else
					printf("Set Time-out to %ld.\n", time);
				break;
			default:
				printf("Invalid input format!\n");
				printUsage();
		}
	}
	
	printf("\n");
	
	close(file_desc);
	
	return 0;
}

